#ifndef _SERVER_MANAGER_H_
#define _SERVER_MANAGER_H_


#include "Common.h"
#include "String.h"
#include "Singleton.h"
#include "Threading/Mutex.h"
#include "enet/enet.h"
#include "json/json.h"
#include "json/value.h"
 
#include <map>

//class Json::Value;

typedef struct _server_hub_tag_
{
	uint32		uplink_id;	//上级管理服务器的ID
	String		uplink_ip;	//上级管理服务器的IP地址
	int		uplink_port;	//上级管理服务器的端口
	String		uplink_pass;	//上级管理服务器的Pass
	String		hub_ip;		//本级HUB的IP地址
	int		hub_port;	//本级HUB的端口
	String		hub_pass;	//本级端口连接的密码
	uint32		hub_maxconnects; //HUB最大的连接数


	_server_hub_tag_()
	{
		uplink_id = 0;      
		uplink_ip = "";      
		uplink_port = 0;    
		uplink_pass = "";    
		hub_ip = "";         
		hub_port = 0;       
		hub_pass = "";       
		hub_maxconnects = 64;
	}

}ServerHubInfo_t;

typedef struct _server_peer_info_tag_
{
	uint32		uplink_id;	//连接父级服务器ID
	uint32		server_id;	//连接的服务器ID
	bool		is_battle;	//是否战斗服务器
	uint32		last_time;	//最后的激活时间
	uint32		start_time;	//启动时间
	bool		is_auth;	//是否已经验证

	_server_peer_info_tag_()
	{
		uplink_id = 0;
		server_id = 0;
		is_battle = false;
		last_time  = 0;
		start_time = now();
		is_auth = false;
	}
}PeerInfo_t;

class SERVER_DECL ServerManager: public Singleton< ServerManager > 
{
public:
	enum ServerCommandType
	{
		ServerCommandTypeNone		= 	0,	//无效的服务器命令类型
		ServerCommandTypePing		= 	1,	//服务器心跳指令
		ServerCommandTypeLogin		=	2,	//服务器登录指令
		ServerCommandTypeForward	=	3,	//服务器指令转发
		ServerCommandTypeSave		=	4,	//服务器指令回写
		ServerCommandTypeServerJoin	=	5,	//服务器加入
		ServerCommandTypeServerPart	=	6,	//服务器分裂
		ServerCommandTypeUser		=	1000,	//用户定义的Command类型
	};
public:
	ServerManager();
	~ServerManager();

	void    Startup(const uint32 & server_id,const uint32 & gid,const bool & isBattle,const ServerHubInfo_t & hub_info);
	void    Shutdown(void);

	//父级连接检测
	bool 	startUplinkLoop(void);
	//Hub连接检测
	bool 	startHUBLoop(void);
	
	//父级连接检测
	bool 	checkUplink(const uint32 & now_time);
	//Hub连接检测
	bool 	checkHUB(const uint32 & now_time);
	
	//发送令包,如果目的服务器的ID为0，则为广播信息包,源服务器ID默认的本服务器ID
	bool	SendGatewayCommand(GatewayCommand * cmd,const uint8 & type = ServerCommandTypeForward,const uint32 & dest_server = 0);

	//发送广播包

	bool Broadcast(const uint16 & cmd, Json::Value & data, const uint32 & dest_server = 0);
	bool BroadcastWithoutPeer(const uint16 & cmd, Json::Value & data, const uint32 & dest_server = 0,ENetPeer * peer = 0);
	
	void Broadcast(const String & packet);
	void Broadcast(const char * packet,const uint32 & len);
	void BroadcastWithoutPeer(const String & packet,ENetPeer * peer = 0);
	void BroadcastWithoutPeer(const char * packet,const uint32 & len,ENetPeer * peer = 0);

	//转换命令结构到JSON
	bool	GatewayCommandToJSON(GatewayCommand * cmd,Json::Value * value);
	//转换命令结构到JSON String
	String	GatewayCommandToJString(GatewayCommand * cmd);
	//转换JSON到命令结构
	bool	JsonToGatewayCommand(Json::Value * value,GatewayCommand * cmd);
	//转换JSON字符串到命令结构
	GatewayCommand *  JStringToGatewayCommand(const String & jstr);

	bool	saveGatewayCommandDB(GatewayCommand * cmd);
	bool	addGatewayCommandDB(GatewayCommand * cmd);

protected:
	bool	uplinkConnecnt(void);		//连接父级服务器
	bool	uplinkLogin(void);		//验证父级连接
	bool	uplinkPing(void);		//服务器心跳包

	//处理信息包
	bool	packetProcess(ENetPeer * peer,ENetPacket * packet);

	//生成服务器分裂包，服务器连接包字符串
	String  getJoinPacketString(PeerInfo_t * peerinfo);
	String	getPartPacketString(PeerInfo_t * peerinfo);
	
private:
        uint32          m_default_gid;
        uint32          m_server_id;
        bool            m_battle_server;

	ServerHubInfo_t		m_hub_info;

	ENetHost * 	m_hub_server;	//Hub管理
	ENetHost * 	m_uplink;	//上级管理
	
	ENetPeer *	m_uplink_peer;
	std::set<ENetPeer *> 	m_hub_peer_set;

	bool		m_do_uplink;
	bool		m_do_hub;
 
};



#define   sServerMgr   ServerManager::getSingleton()

#endif
